import datetime
import sys
from paste.exceptions.errormiddleware import handle_exception

class Task(object):

    def __init__(self, recurance, runner,
                 name=None,
                 error_email=None, error_log=None,
                 error_prefix=None):
        self.recurance = recurance
        self.runner = runner
        self.last_run = None
        self.next_run = None
        self.name = name
        self.error_email = error_email
        self.error_log = error_log
        if error_prefix is None:
            if name:
                error_prefix='[task:%s] ' % name
            else:
                error_prefix='[task] '
        self.error_prefix = error_prefix

    def start_on_queue(self, queue):
        if self.next_run is None:
            self.calculate_next_run()
        queue.schedule(self.execute,
                       self.next_run)

    def execute(self, queue):
        self.last_run = datetime.datetime.now()
        self.calculate_next_run()
        try:
            self.runner()
        except:
            exc_info = sys.exc_info()
            handle_exception(
                exc_info,
                error_stream=queue.stderr,
                html=False,
                debug_mode=False,
                error_email=self.error_email or queue.error_email,
                error_log=self.error_log
                error_email_from=queue.error_email_from,
                smtp_server=queue.smtp_server,
                error_subject_prefix=self.error_prefix,
                )
            # @@: Maybe the schedule should be progressively stepped
            # back on error.  Also, there should be limits to the
            # number of exceptions given.
        queue.schedule(self.execute,
                       self.next_run)
        
    def calculate_next_run(self):
        last = self.last_run
        if last is None:
            self.next_run = datetime.datetime.now()
            return
        self.next_run = self.last_run + self.recurance
